package com.hxs.hxsserver.utils;


import java.util.zip.CRC32;

/**
 * @author liuchuan
 * @create 2024/10/8
 */
public class CRCUtil {

    public static String calculateCRC(byte[] data) {
        CRC32 crc = new CRC32();
        crc.update(data);
        long crcValue = crc.getValue();

        // 取 CRC 值的最后 4 位并转换为四位十六进制字符串
        String crcHex = String.format("%04x", crcValue & 0xFFFF); // 只保留最后 4 位
        System.out.println(crcHex);
        String crcHex2 = String.format("%08x", crcValue);
        System.out.println(crcHex2);
        return crcHex2;
    }
    // CRC-16算法
    public static String calculateCRC16_(byte[] data) {
        int crc = 0xFFFF; // 初始值
        for (byte b : data) {
            crc ^= b; // 逐字节异或
            for (int i = 0; i < 8; i++) {
                // 检查最低位
                if ((crc & 0x0001) != 0) {
                    crc = (crc >> 1) ^ 0xA001; // 如果最低位为1，则右移并与多项式异或
                } else {
                    crc >>= 1; // 右移
                }
            }
        }
        // 返回16位的CRC值，以16进制字符串格式表示
        return String.format("%04X", crc & 0xFFFF);
    }


    // CRC 计算函数
    public static String crcRtu(byte[] data) {
        int crc = 0xFFFF;  // 初始化 CRC 值
        for (int i = 0; i < data.length; i++) {
            crc ^= (data[i] & 0xFF);  // CRC 和当前字节异或
            for (int bit = 0; bit < 8; bit++) {
                if ((crc & 1) != 0) {  // 如果 CRC 的最低位是 1
                    crc >>= 1;           // CRC 右移一位
                    crc ^= 0xA001;       // 与多项式 0xA001 异或
                } else {
                    crc >>= 1;           // CRC 右移一位
                }
            }
        }
        // 反转 CRC 的高低字节
        crc = ((crc >> 8) & 0xFF) | ((crc & 0xFF) << 8);  // 反转字节
        return String.format("%04X", crc);
    }



    public static void main(String[] args) {
        byte[] data = {
                (byte) 0x5A, (byte) 0xA5, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04
        };

        System.out.println(CRCUtil.crcRtu(data));
        System.out.println(CRCUtil.crcRtu(ByteUtil.hexStringToByteArray("5AA50000000004")));
    }

}
